{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0894a735",
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig\n",
    "import torch\n",
    "import json\n",
    "\n",
    "TORCH_DTYPE = 'bfloat16'\n",
    "nf4_config = BitsAndBytesConfig(\n",
    "    load_in_4bit=True,\n",
    "    bnb_4bit_quant_type='nf4',\n",
    "    bnb_4bit_use_double_quant=True,\n",
    "    bnb_4bit_compute_dtype=getattr(torch, TORCH_DTYPE)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6daae66f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)okenizer_config.json:   0%|          | 0.00/915 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading tokenizer.model:   0%|          | 0.00/493k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)/main/tokenizer.json:   0%|          | 0.00/1.80M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)cial_tokens_map.json:   0%|          | 0.00/414 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tokenizer = AutoTokenizer.from_pretrained('mesolitica/malaysian-mistral-7b-32k-instructions')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0da5df04",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a0ae2e1d59eb48d68a17454c0856756e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)lve/main/config.json:   0%|          | 0.00/633 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2023-11-12 14:47:16,973] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "bf11565898764fd8abc2f78102a852dd",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)fetensors.index.json:   0%|          | 0.00/23.9k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "61f5c6f97e2b439680130394b219081c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading shards:   0%|          | 0/3 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "10aa72c443ea40e38360a2cb3c6120d9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)of-00003.safetensors:   0%|          | 0.00/4.94G [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "aa459213396d4d1d99beb4e0492f7bc1",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)of-00003.safetensors:   0%|          | 0.00/5.00G [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "962f85df6b3b4a09b55fb0e084414b2e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)of-00003.safetensors:   0%|          | 0.00/4.54G [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a1b4394ed2704d57947585bd84d73905",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Loading checkpoint shards:   0%|          | 0/3 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c60a3c2fb25542dc95e96a6e54ffff9b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)neration_config.json:   0%|          | 0.00/111 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model = AutoModelForCausalLM.from_pretrained(\n",
    "    'mesolitica/malaysian-mistral-7b-32k-instructions',\n",
    "    use_flash_attention_2 = True,\n",
    "    quantization_config = nf4_config\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f18b9442",
   "metadata": {},
   "outputs": [],
   "source": [
    "def parse_mistral_chat(messages, function_call = None):\n",
    "\n",
    "    user_query = messages[-1]['content']\n",
    "\n",
    "    users, assistants = [], []\n",
    "    for q in messages[:-1]:\n",
    "        if q['role'] == 'user':\n",
    "            users.append(q['content'])\n",
    "        elif q['role'] == 'assistant':\n",
    "            assistants.append(q['content'])\n",
    "\n",
    "    texts = ['<s>']\n",
    "    \n",
    "    if function_call:\n",
    "        fs = []\n",
    "        for f in function_call:\n",
    "            f = json.dumps(f, indent=4)\n",
    "            fs.append(f)\n",
    "        fs = '\\n\\n'.join(fs)\n",
    "        texts.append(f'\\n[FUNCTIONCALL]\\n{fs}\\n')\n",
    "        \n",
    "    for u, a in zip(users, assistants):\n",
    "        texts.append(f'[INST] {u.strip()} [/INST] {a.strip()}</s>')\n",
    "\n",
    "    texts.append(f'[INST] {user_query.strip()} [/INST]')\n",
    "    prompt = ''.join(texts).strip()\n",
    "    return prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "ecd9d61a",
   "metadata": {},
   "outputs": [],
   "source": [
    "f = { \"name\": \"get_exchange_rate\", \"description\": \"Get the exchange rate between two currencies\", \"parameters\": { \"type\": \"object\", \"properties\": { \"base_currency\": { \"type\": \"string\", \"description\": \"The currency to convert from\" }, \"target_currency\": { \"type\": \"string\", \"description\": \"The currency to convert to\" } }, \"required\": [ \"base_currency\", \"target_currency\" ] } }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "543bd595",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<s> \n",
      "[FUNCTIONCALL]\n",
      "{\n",
      "    \"name\": \"get_exchange_rate\",\n",
      "    \"description\": \"Get the exchange rate between two currencies\",\n",
      "    \"parameters\": {\n",
      "        \"type\": \"object\",\n",
      "        \"properties\": {\n",
      "            \"base_currency\": {\n",
      "                \"type\": \"string\",\n",
      "                \"description\": \"The currency to convert from\"\n",
      "            },\n",
      "            \"target_currency\": {\n",
      "                \"type\": \"string\",\n",
      "                \"description\": \"The currency to convert to\"\n",
      "            }\n",
      "        },\n",
      "        \"required\": [\n",
      "            \"base_currency\",\n",
      "            \"target_currency\"\n",
      "        ]\n",
      "    }\n",
      "}\n",
      "[INST] tolong tukar 10 ringgit ke usd [/INST] <functioncall> {\"name\": \"get_exchange_rate\", \"arguments\": '{\"base_currency\": \"10 ringgit\", \"target_currency\": \"USD\"}'} \n",
      "\n",
      "\n",
      "<functioncall> {\"exchange_rate\": 0.1457}</s>\n"
     ]
    }
   ],
   "source": [
    "messages = [\n",
    "    {'role': 'user', 'content': 'tolong tukar 10 ringgit ke usd'}\n",
    "]\n",
    "prompt = parse_mistral_chat(messages, function_call = [f])\n",
    "inputs = tokenizer([prompt], return_tensors='pt', add_special_tokens=False).to('cuda')\n",
    "generate_kwargs = dict(\n",
    "    inputs,\n",
    "    max_new_tokens=128,\n",
    "    top_p=0.95,\n",
    "    top_k=50,\n",
    "    temperature=0.9,\n",
    "    do_sample=True,\n",
    "    num_beams=1,\n",
    ")\n",
    "r = model.generate(**generate_kwargs)\n",
    "print(tokenizer.decode(r[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "07881cfc",
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    {'role': 'user', 'content': 'kwsp tu apa'},\n",
    "    {'role': 'assistant', 'content': 'KWSP adalah singkatan bagi Kumpulan Wang Simpanan Pekerja, sebuah badan berkanun yang ditubuhkan oleh kerajaan Malaysia untuk menguruskan simpanan persaraan untuk pekerja di Malaysia. KWSP adalah salah satu kumpulan simpanan persaraan terbesar di dunia, dengan lebih 18 juta ahli aktif dan aset bernilai lebih $690 bilion.'},\n",
    "    {'role': 'user', 'content': 'ye ke'},\n",
    "]\n",
    "prompt = parse_mistral_chat(messages)\n",
    "inputs = tokenizer([prompt], return_tensors='pt', add_special_tokens=False).to('cuda')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "67d3c231",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'<s> [INST] kwsp tu apa [/INST] KWSP adalah singkatan bagi Kumpulan Wang Simpanan Pekerja, sebuah badan berkanun yang ditubuhkan oleh kerajaan Malaysia untuk menguruskan simpanan persaraan untuk pekerja di Malaysia. KWSP adalah salah satu kumpulan simpanan persaraan terbesar di dunia, dengan lebih 18 juta ahli aktif dan aset bernilai lebih $690 bilion.</s> [INST] ye ke [/INST] Sudah tentu! KWSP bukan sekadar simpanan, ia merupakan institusi yang memainkan peranan penting dalam ekonomi Malaysia, menyediakan simpanan persaraan untuk pekerja dan membantu menyokong pembangunan ekonomi negara. KWSP juga mempunyai portfolio pelaburan yang luas, merangkumi pelbagai kelas aset yang membantu memastikan simpanan ahlinya kekal stabil dari semasa ke semasa.</s>'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generate_kwargs = dict(\n",
    "    inputs,\n",
    "    max_new_tokens=1024,\n",
    "    top_p=0.95,\n",
    "    top_k=50,\n",
    "    temperature=0.9,\n",
    "    do_sample=True,\n",
    "    num_beams=1,\n",
    ")\n",
    "r = model.generate(**generate_kwargs)\n",
    "tokenizer.decode(r[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4efaf03f",
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    {'role': 'user', 'content': 'camne nak kill pid dalam linux'}\n",
    "]\n",
    "prompt = parse_mistral_chat(messages)\n",
    "inputs = tokenizer([prompt], return_tensors='pt', add_special_tokens=False).to('cuda')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bdc41dda",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<s> [INST] camne nak kill pid dalam linux [/INST] Untuk membunuh proses dalam Linux, anda boleh menggunakan perintah `kill`. Sintaks perintah ini ialah `kill [pid]`. Anda boleh menghantar nombor pid proses sebagai argumen kepada perintah ini, dan anda juga boleh menghantar isyarat untuk membunuh proses. Contohnya:\n",
      "\n",
      "- Untuk membunuh proses dengan pid 1234, anda boleh menjalankan:\n",
      "   ```\n",
      "   kill 1234\n",
      "   ```\n",
      "- Untuk membunuh proses dengan isyarat SIGINT, anda boleh menjalankan:\n",
      "   ```\n",
      "   kill -SIGINT 1234\n",
      "   ```\n",
      "Perlu diingatkan bahawa membunuh proses memerlukan kepada anda mempunyai pengetahuan yang baik tentang sistem Linux dan pengurusan proses, dan juga memahami potensi akibatnya. Adalah disyorkan untuk menggunakan perintah ini dengan berhati-hati dan hanya jika diperlukan.</s>\n"
     ]
    }
   ],
   "source": [
    "generate_kwargs = dict(\n",
    "    inputs,\n",
    "    max_new_tokens=1024,\n",
    "    top_p=0.95,\n",
    "    top_k=50,\n",
    "    temperature=0.9,\n",
    "    do_sample=True,\n",
    "    num_beams=1,\n",
    ")\n",
    "r = model.generate(**generate_kwargs)\n",
    "print(tokenizer.decode(r[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6581db3c",
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    {'role': 'user', 'content': 'awat malaysia ada jabatan koko, malaysia bukan keluaq koko banyak pun'}\n",
    "]\n",
    "prompt = parse_mistral_chat(messages)\n",
    "inputs = tokenizer([prompt], return_tensors='pt', add_special_tokens=False).to('cuda')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7a0d491e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<s> [INST] awat malaysia ada jabatan koko, malaysia bukan keluaq koko banyak pun [/INST] Ini adalah kerana Malaysia bukan sahaja mempunyai kawasan tanah yang besar yang digunakan untuk kelapa, tetapi juga tanah dan sumber lain yang boleh digunakan untuk tanaman lain. Selain itu, tumpuan kerajaan terhadap sektor perindustrian dan pembuatan mungkin menyumbang kepada kemerosotan industri koko di negara ini. Walau bagaimanapun, terdapat usaha untuk meningkatkan pengeluaran koko melalui skim dan program tertentu.</s>\n"
     ]
    }
   ],
   "source": [
    "generate_kwargs = dict(\n",
    "    inputs,\n",
    "    max_new_tokens=1024,\n",
    "    top_p=0.95,\n",
    "    top_k=50,\n",
    "    temperature=0.9,\n",
    "    do_sample=True,\n",
    "    num_beams=1,\n",
    ")\n",
    "r = model.generate(**generate_kwargs)\n",
    "print(tokenizer.decode(r[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "27b0ea0b",
   "metadata": {},
   "outputs": [],
   "source": [
    "s = \"\"\"\n",
    "Pilih jawapan yang tepat untuk soalan tersebut.\n",
    "Soalan: Perkara yang ....... jika dibesarkan akan menimbulkan kesan buruk.\n",
    "A. riuh-rendah\n",
    "B. kusut-masai\n",
    "C. remeh-temeh\n",
    "D. kacau-bilau\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "3dc555f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    {'role': 'user', 'content': s.strip()}\n",
    "]\n",
    "prompt = parse_mistral_chat(messages)\n",
    "inputs = tokenizer([prompt], return_tensors='pt', add_special_tokens=False).to('cuda')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "178e5e4e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<s> [INST] Pilih jawapan yang tepat untuk soalan tersebut.\n",
      "Soalan: Perkara yang ....... jika dibesarkan akan menimbulkan kesan buruk.\n",
      "A. riuh-rendah\n",
      "B. kusut-masai\n",
      "C. remeh-temeh\n",
      "D. kacau-bilau [/INST] Jawapannya ialah B. kusut-masai.</s>\n"
     ]
    }
   ],
   "source": [
    "generate_kwargs = dict(\n",
    "    inputs,\n",
    "    max_new_tokens=1024,\n",
    "    top_p=0.95,\n",
    "    top_k=50,\n",
    "    temperature=0.9,\n",
    "    do_sample=True,\n",
    "    num_beams=1,\n",
    ")\n",
    "r = model.generate(**generate_kwargs)\n",
    "print(tokenizer.decode(r[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a331139f",
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    {'role': 'user', 'content': 'contoh sentiment analysis guna sklearn'}\n",
    "]\n",
    "prompt = parse_mistral_chat(messages)\n",
    "inputs = tokenizer([prompt], return_tensors='pt', add_special_tokens=False).to('cuda')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6af2e679",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<s> [INST] contoh sentiment analysis guna sklearn [/INST] Sentiment analysis adalah teknik pembelajaran mesin yang menganalisis data teks untuk menentukan sentimen atau sikap terhadap sesuatu topik, produk atau perkhidmatan. Terdapat pelbagai kaedah untuk melakukan analisis sentimen, termasuk pendekatan berasaskan peraturan dan pembelajaran mesin.\n",
      "\n",
      "Salah satu kaedah analisis sentimen yang paling popular adalah menggunakan perpustakaan Natural Language Processing (NLP) seperti NLTK dalam Python. NLTK adalah perpustakaan yang berkuasa untuk tugas NLP yang termasuk analisis sentimen.\n",
      "\n",
      "Berikut adalah contoh bagaimana anda boleh menggunakan NLTK untuk melakukan analisis sentimen pada sekeping teks:\n",
      "\n",
      "```python\n",
      "import nltk\n",
      "from nltk.corpus import stopwords\n",
      "from nltk.tokenize import word_tokenize, sent_tokenize\n",
      "\n",
      "# Takrifkan teks untuk menganalisis\n",
      "text = 'Saya sangat suka produk ini! Ia adalah perkara terbaik yang pernah ada.'\n",
      "\n",
      "# Tukar teks kepada perkataan dan tokenize into ayat\n",
      "sentences = sent_tokenize(text)\n",
      "words = word_tokenize(sentences)\n",
      "\n",
      "# Buang kata henti\n",
      "stop_words = set(stopwords.words('english'))\n",
      "words = [word.lower() for word in words if word.lower() not in stop_words]\n",
      "\n",
      "# Lakukan analisis sentimen menggunakan NLTK\n",
      "sentiment = nltk.sentiment.Analyzer(user_language=None)\n",
      "\n",
      "# Cetak skor sentimen\n",
      "print(sentiment.polarity_scores(text))\n",
      "```\n",
      "\n",
      "Skor sentimen adalah senarai skor positif, negatif, neutral, dan kompaun teks. Dalam contoh ini, skor sentimen akan menunjukkan skor positif yang tinggi untuk ayat pertama dan skor negatif yang rendah untuk ayat kedua kerana ulasan secara keseluruhan positif.\n",
      "\n",
      "Anda boleh menggunakan skor sentimen ini untuk membuat keputusan berdasarkan teks, seperti sama ada untuk membeli atau menjual produk tertentu. Anda juga boleh menggunakan teknik analisis sentimen lanjutan seperti pembelajaran mesin untuk menganalisis sejumlah besar teks dan menghasilkan skor sentimen yang lebih tepat.</s>\n"
     ]
    }
   ],
   "source": [
    "generate_kwargs = dict(\n",
    "    inputs,\n",
    "    max_new_tokens=1024,\n",
    "    top_p=0.95,\n",
    "    top_k=50,\n",
    "    temperature=0.9,\n",
    "    do_sample=True,\n",
    "    num_beams=1,\n",
    ")\n",
    "r = model.generate(**generate_kwargs)\n",
    "print(tokenizer.decode(r[0]))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
